<?php
/**
 * Base (static) class for the refworks module.
 * Should be included on all pages
 * Contains methods for general page use - e.g. initialisation, headers etc
 *
 * @copyright &copy; 2009 The Open University
 * @author j.platts@open.ac.uk
 * @author Author_Name_2@open.ac.uk
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @package refworks
 */

require_once(dirname(dirname(dirname(__FILE__))).'/config.php');
include_once(dirname(__FILE__).'/lib.php');
include_once(dirname(__FILE__).'/refworks_connect.php');
require_once(dirname(__FILE__).'/refworks_folder_api.php');
require_once(dirname(__FILE__).'/../../local/references/rwapi/rwapi.php');
include_once(dirname(__FILE__).'/collab/refworks_collab_lib.php');

class refworks_base {
    public static $course = null;
    public static $cm = null;
    public static $instance = null;

    public static $isinstance = false;

    public static $baseloc = 'mod/refworks';

    private static $hasleftmenu = false;

    /**
     * Initialise the page, setting up moodle vars, checking login
     * Also sets up whether access has come from instance or direct
     * THIS MUST BE CALLED BY ALL PAGES IN THE MODULE
     * @return
     */
    public static function init() {
        $id = optional_param('id', 0, PARAM_INT); // course_module ID, or
        $a  = optional_param('a', 0, PARAM_INT);  // refworks instance ID

        if ($id) {
            if (! $cm = get_coursemodule_from_id('refworks', $id)) {
                error('Course Module ID was incorrect');
            }

            if (! $course = get_record('course', 'id', $cm->course)) {
                error('Course is misconfigured');
            }

            if (! $refworks = get_record('refworks', 'id', $cm->instance)) {
                error('Course module is incorrect');
            }
            self::$isinstance = true;
            self::$cm = $cm;
            self::$course = $course;
            self::$instance = $refworks;
        } else if ($a) {
            if (! $refworks = get_record('refworks', 'id', $a)) {
                error('Course module is incorrect');
            }
            if (! $course = get_record('course', 'id', $refworks->course)) {
                error('Course is misconfigured');
            }
            if (! $cm = get_coursemodule_from_instance('refworks', $refworks->id, $course->id)) {
                error('Course Module ID was incorrect');
            }
            self::$isinstance = true;
            self::$cm = $cm;
            self::$course = $course;
            self::$instance = $refworks;
        } else {
            //direct access
        }
        //require logged in to moodle
        if(self::$isinstance){
            require_login(self::$course, true, self::$cm);
        }else{
            require_login(0, true);
        }

        global $CFG;
        //set the base folder location of this mod (used in links/css etc so we can have sub-folders)
        self::$baseloc = $CFG->wwwroot.'/'.self::$baseloc.'/';
    }

    /**
     * Prints header, changes breadcrumb depending on whether instance or standalone
     * @param $breadcrumbs array: array of moodle breadcrumb array (optional)
     * @return
     */
    public static function write_header($breadcrumbs=array()){
        GLOBAL $CFG;

        // Breadcrumb module title - always try and use title from admin settings, if not use lang file
        if(!empty($CFG->refworks_name)){
            $strrefworks  = $CFG->refworks_name;
        }else{
            $strrefworks  = get_string('modulename', 'refworks');
        }

        $navlinks = array();
        if(self::$isinstance){
            $navlinks[] = array('name' => $strrefworks, 'link' => self::$baseloc."view.php?id=".self::$cm->id, 'type' => 'refworks');
        }else{
            $navlinks[] = array('name' => $strrefworks, 'link' => self::$baseloc."index.php", 'type' => 'refworks');
        }
        if(count($breadcrumbs>0)){
            for($a=0,$max=count($breadcrumbs);$a<$max;$a++){
                $navlinks[] = $breadcrumbs[$a];
            }
        }

        $navigation = build_navigation($navlinks);

        //HEAD code (css, js meta tags etc)
        $meta = '<link rel="stylesheet" type="text/css" href="'.self::$baseloc.'refworks.css" />';
        $meta .= '<link rel="stylesheet" type="text/css" href="'.self::$baseloc.'refworks_p.css" media="print" />';
        //remove whitespace (saves bytes on download)
        //$meta = preg_replace('/\s\s+/', '', trim($meta));

        if(self::$isinstance){
            print_header_simple(htmlspecialchars(format_string(self::$instance->name)), '', $navigation, '', $meta, true,
            update_module_button(self::$cm->id, self::$course->id, $strrefworks), navmenu(self::$course, self::$cm));
        }else{
            print_header_simple(htmlspecialchars($strrefworks), '', $navigation, '' , $meta);
        }

        //wrapper div for all module content
        print('<div id="refcontent">');
    }

    /**
     * Creates footer code
     * @return
     */
    public static function write_footer(){
        if (self::$hasleftmenu){
            //write end tag for central div
            echo('</div>');
        }
        echo('</div>');//refcontent div close
        //clear
        echo('<div class="clearer"></div>');
        //js file is loaded at end to increase download speed
        require_js(self::$baseloc.'refworks.js');
        print_footer();
    }

    /**
     * prints out the side menu, you must call this after header and before writing any content
     * @param $curfile string:file name of current file (matched to items to highlight current)
     * @return
     */
    public static function write_sidemenu($curfile='', $cursharedacct=''){
        self::$hasleftmenu = true;
        echo('<div id="left-column">');

        //Print calender block (if instance)
        if(self::$isinstance){
            GLOBAL $CFG, $PAGE;
            require_once(dirname(__FILE__).'/pagelib.php');
             
            // Initialize $PAGE, compute blocks
            $PAGE       = page_create_instance(self::$cm->instance);
            $pageblocks = blocks_setup($PAGE);

            $editing=isediting(self::$course->id);
            if(($hasleft=blocks_have_content($pageblocks, BLOCK_POS_LEFT)) || $editing) {
                blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT);
            }
        }
        //div for module side menu (needs own css rules)
        echo('<div id="sidemenu">');
        /*menu array and sub arrays defining menu structure
         * menuararray - each element (array) represents a side block
         * menu block array, assoc array - title:heading , reqcap:comma sep list of capabilities needed to show block, items:array of menu items
         * item assoc array - title:link text, link:url, reqcap:comma sep list of capabilities needed to show item, style:string class of item
         */
        $menuarray = array(
        array(
            'title' => get_string('references','refworks'),
            'reqcap' => 'mod/refworks:connect',
            'items' => array(
        array('title' => get_string('view_all_refs','refworks'), 'link' => 'viewrefs.php'),
        array('title' => get_string('create_ref','refworks'), 'link' => 'createref.php', 'reqcap' => 'mod/refworks:update'),
        array('title' => get_string('import_ref','refworks'), 'link' => 'importrefs.php'),
        array('title' => get_string('export_ref','refworks'), 'link' => 'exportrefs.php', 'reqcap' => 'mod/refworks:export'),
        array('title' => get_string('create_bib','refworks'), 'link' => 'createbib.php', 'reqcap' => 'mod/refworks:bibliography'),
        array('title' => get_string('reports','refworks'), 'link' => 'reports/report.php', 'reqcap' => 'mod/refworks:runreport')
        )
        ),
        array(
            'title' => get_string('folders','refworks'),
            'reqcap' => 'mod/refworks:folders',
            'items' => array(
        array('title' => get_string('create_folder','refworks'), 'link' => 'createfolder.php'),
        array('title' => get_string('manage_folder','refworks'), 'link' => 'managefolders.php')
        )
        ),
        //Collaborative
        array(
            'title' => get_string('team_accounts','refworks'),
        	'reqcap' => 'mod/refworks:collaboration',
            'items' => array(
        array('title' => get_string('team_createacc','refworks'), 'link' => 'collab/collab_create.php', 'reqcap'=>'mod/refworks:collaboration_createacc'),
        array('title' => get_string('team_manageacc','refworks'), 'link' => 'collab/collab_manage.php', 'reqcap'=>'mod/refworks:collaboration_createacc'),
        )
        ),
        array(
            'title' => get_string('refworks','refworks'),
        	'reqcap' => 'refworks',
            'items' => array(
        array('title' => get_string('access_account','refworks'), 'link' => 'http://www.refworks.com/refworks'),
        )
        ),
        array(
            'title' => get_string('support','refworks'),
            'items' => array(
        array('title' => get_string('access_help','refworks'), 'link' => 'https://www.refworks.com/RWSingle/help/helpmainframe.asp'),
        )
        )
        );

        //Add user folders to folder block
        refworks_folder_api::update_folder_list();
        for($max=count(refworks_folder_api::$folders)-1;$max>-1;$max--){
            array_unshift($menuarray[1]['items'], array('title' => refworks_base::return_foldername(refworks_folder_api::$folders[$max]['name'],true), 'link' => 'viewfolder.php?folder='.urlencode(refworks_folder_api::$folders[$max]['name']), 'style' => 'folder'));
        }

        if(self::check_capabilities('mod/refworks:collaboration')){
            global $USER, $SESSION;
            //Collaboration - Check if user can access any accounts + add to menu
            if(count(refworks_collab_lib::get_user_accounts($USER->id))>0){
                array_push($menuarray[2]['items'], array('title' => get_string('team_login','refworks')));
                foreach(refworks_collab_lib::$accsavail as $acc){
                    array_push($menuarray[2]['items'], array('title' => stripslashes($acc->name), 'link'=>'collab/collab_login.php?accid='.$acc->id, 'style'=>'account'));
                }
            }
            //If user is logged in to an account - present them with a logout option
            if(isset($SESSION->rwteam)){
                array_push($menuarray[2]['items'], array('title' => get_string('team_logout','refworks'), 'link'=>'collab/collab_logout.php'));
                  //In a shared account, add publish link to folder menu
                array_push($menuarray[1]['items'], array('title' => get_string('share_folder','refworks'), 'link' => 'sharefolders.php'));
                $cursharedacct = 'collab/collab_login.php?accid='.$SESSION->rwteam;
            }
        }

        //create menu html
        for($a=0, $max=count($menuarray); $a<$max; $a++){
            //check block capabilities so can display
            if(isset($menuarray[$a]['reqcap'])){
                //special case: refworks - check logged in to an individual account
                if($menuarray[$a]['reqcap'] == 'refworks'){
                    if(!refworks_connect::$connectok || isset($SESSION->rwteam)){
                        continue;
                    }
                }else if(!self::check_capabilities($menuarray[$a]['reqcap'])){
                    //user does not have capability so do not show
                    continue;
                }
            }
            $blockcontent = '';
            if(isset($menuarray[$a]['items'])){
                $blockcontent = '<ul class="section">';
                for($b=0, $max2=count($menuarray[$a]['items']); $b<$max2; $b++){
                    //check capabilities so can display item
                    if(isset($menuarray[$a]['items'][$b]['reqcap'])){
                        if(!self::check_capabilities($menuarray[$a]['items'][$b]['reqcap'])){
                            //user does not have capability so do not show
                            continue;
                        }
                    }

                    if(isset($menuarray[$a]['items'][$b]['style'])){
                        //item has a class
                        $blockcontent .= '<li class="'.$menuarray[$a]['items'][$b]['style'].'">';
                    }else{
                        $blockcontent .= '<li>';
                    }
                    //link or not?
                    if(isset($menuarray[$a]['items'][$b]['link']) && $menuarray[$a]['items'][$b]['link']!=''){
                        //check if current option (selected)
                        $linkselected = false;

                        if($curfile == ''){
                            //check link against the current php file
                            //get file name
                            $curfile = substr($_SERVER['PHP_SELF'],strrpos($_SERVER['PHP_SELF'],'/')+1);
                        }

                        if(($menuarray[$a]['items'][$b]['link'] == $curfile) || ($cursharedacct!=='' && $menuarray[$a]['items'][$b]['link'] == $cursharedacct)){
                            $linkselected = true;
                        }

                        $blockcontent .= '<a href="'.self::return_link($menuarray[$a]['items'][$b]['link']).'"><span';
                        if($linkselected){
                            $blockcontent .= ' class="current"';
                        }
                        $blockcontent .= '>'.htmlspecialchars($menuarray[$a]['items'][$b]['title']).'</span></a>';
                    }else{
                        $blockcontent .= '<span>'.htmlspecialchars($menuarray[$a]['items'][$b]['title']).'</span>';
                    }
                    $blockcontent .= '</li>';
                }
                $blockcontent .= '</ul>';
            }
            print_side_block($menuarray[$a]['title'],$blockcontent,NULL,NULL,'',NULL,$menuarray[$a]['title']);
        }



        echo('</div><div class="refworkslogo"><img src="'.self::$baseloc.'refworks.png" alt="Powered by RefWorks"/></div></div>');//end of sidemenu, end of column
        //setup main content column
        echo('<div id="middle-column" class="has-left-column">');
    }

    /**
     * Prints main page title
     * @param $text string
     * @return
     */
    public static function write_heading($text){
        echo('<h1 class="main-title">'.$text.'</h1>');
    }

    public static function write_error($text){
        echo('<div class="box errorbox errorboxcontent">'.$text.'</div>');
    }

    /**
     * Wrapper for moodle has_capability
     * Use this method instead as works in standalone + instance contexts
     * @param $capstr string: capabilities to check (, separated)
     * @return bool: true if user passes all
     */
    public static function check_capabilities($capstr, $userid=0){
        global $CFG;
        $caparr = explode(',',$capstr);
        $capok = true;

        //include capabilities array so we can check context
        require(dirname(__FILE__).'/db/access.php');

        foreach($caparr as $cap){
            //get context level
            $contextlevel = $mod_refworks_capabilities[$cap]['contextlevel'];

            //Gets the current context, based on required level
            if($contextlevel == CONTEXT_MODULE && self::$isinstance){
                $context=get_context_instance(CONTEXT_MODULE, self::$cm->id);
            }else if($contextlevel == CONTEXT_COURSE && self::$isinstance){
                $context=get_context_instance(CONTEXT_COURSE, self::$course->id);
            }else if($contextlevel == CONTEXT_SYSTEM){
                $context=get_context_instance(CONTEXT_SYSTEM);
            }else{
                //unsupported e.g. module context but not a module instance
                if(class_exists('ouflags') && $cap=='mod/refworks:allow_url_override'){
                    //special case for OU where mod context needs to be SAMS dependant
                    $context=get_context_instance(CONTEXT_SYSTEM);
                }else{
                    break;
                }
            }
            
            if($userid==0){
                if(!has_capability($cap, $context)){
                    $capok = false;
                }
            }else{
                if(!has_capability($cap, $context, $userid)){
                    $capok = false;
                }
            }
            // ou-specific begins
            if($userid==0 && class_exists('ouflags')){
                $overridecaps = array('mod/refworks:collaboration','mod/refworks:collaboration_createacc','mod/refworks:runreport','mod/refworks:export_rwxml','mod/refworks:allow_url_override');
                //SAMS override for some capabilities as they will return false for staff - will only work for current user
                //For collaboration - if staff allow, or not disallow
                if(in_array($cap,$overridecaps)){
                    if ((defined('AUTH_SAMS') && AUTH_SAMS == $CFG->auth && class_exists('SamsAuth'))){
                        global $DISABLESAMS;
                        //check if SAMS has been disabled on this page as this will cause error
                        if(isset($DISABLESAMS) && $DISABLESAMS==true){
                                //override for OU, always deny access on disabled SAMS pages to prevent accidental student access to these capabilities
                                $capok = false;
                        }else if(SamsAuth::$inst->match_authids('00000008') || SamsAuth::$inst->match_authids('00000005')) {
                            $capok = true;
                        }else{
                            $capok = false;
                        }
                    }
                }
            }
            // ou-specific ends
        }

        return $capok;
    }

    /**
     * Takes a link and appends instance params (id=) if needed
     * @param $link string:url
     * @return string
     */
    public static function return_link($link){
        //If running as instance and is a php not an external link or another moodle file
        if(strpos($link,'.php')){
            //check not external or another moodle page
            if(!strpos($link,'://') && !strpos($link,'../')){
                if(self::$isinstance){
                    if(strpos($link,'?')===false){
                        $link .= '?id='.self::$cm->id;
                    }else if(strpos($link,'&amp;id')===false){
                        $link .= '&amp;id='.self::$cm->id;
                    }
                }
                return self::$baseloc.$link;
            }
        }
        //external link return as is
        return $link;
    }

    /**
     * Takes a folder name got from optional_param etc and cleans it up to return the exact name
     * so, my+folder becomes my folder
     * @param $fld string: folder name
     * @param $display bool: optional - true if the name is for display to user only
     * @return string : correct folder name
     */
    public static function return_foldername($fld, $display=false){
        $fld = rawurldecode($fld);
        $fld = stripslashes($fld);
        if($display && strpos($fld,'[[')===0 && strpos($fld,']]')){
            //remove [[]] prefix for auto-populated folders
            $fld = substr($fld,strpos($fld,']]')+2);
        }
        return $fld;
    }
}
?>